package com.gcloud.mesh.framework.core.mq;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import com.gcloud.mesh.framework.core.mq.role.MyRole;
import com.gcloud.mesh.framework.core.msg.MsgResolver;
import com.gcloud.mesh.header.msg.MqBaseMsg;

@Component
@ConditionalOnProperty(name = "mesh.mq.enable", havingValue = "true")
public class MsgProducer {

    @Value("${mesh.mq.serverRole}")
    private String serverRole;

    @Value("${mesh.mq.agentRole}")
    private String agentRole;

    @Autowired
    private AmqpTemplate amqpTemplate;

    private boolean serverConnected = false;

    public MqBaseMsg sendToServer(MqBaseMsg msg) {
        return this.send(serverRole, serverRole, msg);
    }

    public MqBaseMsg sendToAgent(String agentId, MqBaseMsg msg) {
        return this.send(agentRole, agentId, msg);
    }

    private MqBaseMsg send(String role, String queue, MqBaseMsg msg) {
        this.amqpTemplate.convertAndSend(role, queue, this.genMessage(msg, false));
        MqBaseMsg reply = SyncReplyMsgs.waitForReply(msg.getMsgId(), 10);
        return reply;
    }

    public void publishToServer(MqBaseMsg msg) {
        this.publish(serverRole, serverRole, msg);
    }

    // 相当于对agent广播
    public void publishToAgent(MqBaseMsg msg) {
        this.publish(agentRole, agentRole, msg);
    }

    public void publishToAgent(String agentId, MqBaseMsg msg) {
        this.publish(agentRole, agentId, msg);
    }

    private void publish(String role, String queue, MqBaseMsg msg) {
        this.amqpTemplate.convertAndSend(role, queue, this.genMessage(msg, true));
    }

    private Message genMessage(MqBaseMsg msg, boolean async) {
        MessageProperties props = new MessageProperties();
        props.setHeader("action", MsgResolver.getAction(msg.getClass()));
        props.setHeader("msgId", msg.getMsgId());
        props.setHeader("reply", false);
        props.setHeader("async", async);
        props.setHeader("role", MyRole.roleVo().getRole());
        props.setHeader("roleId", MyRole.roleVo().getId());
        return new Message(MqMsgSerializer.serialize(msg), props);
    }

    public void updateServerConnected(boolean connected) {
        this.serverConnected = connected;
    }

    public boolean isServerConnected() {
        return this.serverConnected;
    }
}
